/* 
 * File:   OptionUtil.h
 * Author: bdeng
 *
 * Created on March 17, 2011, 9:20 PM
 */

#include <cmath>
#include <string>

using namespace std;

#ifndef OPTIONUTIL_H
#define	OPTIONUTIL_H
class OptionUtil
{

public:
    //distributions
    static double ND(double x);
    static double CND(double x);
    static double CND2(double x);
    static double BND(double X, double y, double rho);
    static double CBND(double X, double y, double rho);
    static double CBND2(double A,double b, double rho);
    static double CBND3(double A, double b, double rho);
    static double CBND4(double A, double b, double rho);
    static double CBNDGeneral(int TypeFlag, double X, double y, double rho);
    static double CNDEV(double p);


    static double ConvertingToCCRate(double r, double Compoundings)
    {
            return (Compoundings == 0) ? r : Compoundings * log(1.0 + r / Compoundings);
    }


    //Black Scholes Merton

    static double GBlackScholes(string CallPutFlag, double S, double x,
            double T, double r, double b, double v);
    static double Black76(string CallPutFlag, double F, double x, double T, double r, double v);
    static double GarmanKolhagen(string CallPutFlag,double S,double x,
            double T,double r,double rf,double v);
    static double GDdeltaDvol(double S, double x, double T, double r, double b, double v);
    static double GDdeltaDvolDvol(double S, double x, double T, double r, double b, double v);
    static double GVegaFromDelta(double S, double T, double r, double b, double delta);
    static double GGammaFromDelta(double S, double T, double r, double b, double v, double delta);
    static double GRNDFromInTheMoneyProb(double x, double T, double r, double v, double Probability);
    static double GGammaPFromDelta(double S, double T, double r, double b, double v, double delta);
    static double GVegaPFromDelta(double S, double T, double r, double b, double v, double delta);
    static double MaxDdeltaDvolAsset(string UpperLowerFlag, double x, double T, double b, double v);
    static double MaxDdeltaDvolStrike(string UpperLowerFlag, double S, double T, double b, double v);
    static double GMaxGammaVegaatX(double S, double b, double T, double v);
    static double GMaxGammaatS(double x, double b, double T, double v);
    static double GMaxVegaatS(double x, double b, double T, double v);
    static double GForwardDelta(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GDzetaDvol(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GDzetaDtime(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GInTheMoneyProbability(string CallPutFlag, double S, double x, double T, double b, double v);
    static double GBreakEvenProbability(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GStrikeFromInTheMoneyProb(string CallPutFlag, double S, double v, double T, double b, double InTheMoneyProb);
    static double GStrikeFromDelta(string CallPutFlag, double S, double T, double r, double b, double v, double delta);
    static double InTheMoneyProbFromDelta(string CallPutFlag, double S, double T, double r, double b, double v, double delta);
    static double GDeltaFromInTheMoneyProb(string CallPutFlag, double S, double T, double r, double b, double v, double InTheMoneyProb);
    static double GDeltaMirrorStrike(double S, double T, double b, double v);
    static double GProbabilityMirrorStrike(double S, double T, double b, double v);
    static double GDeltaMirrorCallPutStrike(double S, double x, double T, double b, double v);
    static double GGamma(double S, double x, double T, double r, double b, double v);
    static double GSaddleGamma(double x, double T, double r, double b, double v);
    static double GGammaP(double S, double x, double T, double r, double b, double v);
    static double GDelta(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GStrikeDelta(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GElasticity(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GDgammaDvol(double S, double x, double T, double r, double b, double v);
    static double GDgammaPDvol(double S, double x, double T, double r, double b, double v);
    static double GDgammaDspot(double S, double x, double T, double r, double b, double v);
    static double GDgammaPDspot(double S, double x, double T, double r, double b, double v);
    static double GRiskNeutralDensity(double S, double x, double T, double r, double b, double v);
    static double GTheta(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GThetaDriftLess(double S, double x, double T, double r, double b, double v);
    static double GVarianceVega(double S, double x, double T, double r, double b, double v);
    static double GVarianceVomma(double S, double x, double T, double r, double b, double v);
    static double GVarianceUltima(double S, double x, double T, double r, double b, double v);
    static double GVarianceDelta(double S, double x, double T, double r, double b, double v);
    static double GVega(double S, double x, double T, double r, double b, double v);
    static double GVegaP(double S, double x, double T, double r, double b, double v);
    static double GDdeltaDtime(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GProfitLossSTD(string TypeFlag, string CallPutFlag, double S, double x, double T, double r, double b, double v, int NHedges);
    static double GDvegaDvol(double S, double x, double T, double r, double b, double v);
    static double GDvegaPDvol(double S, double x, double T, double r, double b, double v);
    static double GDvegaDtime(double S, double x, double T, double r, double b, double v);
    static double GDvommaDvol(double S, double x, double T, double r, double b, double v);
    static double GDgammaDtime(double S, double x, double T, double r, double b, double v);
    static double GDgammaPDtime(double S, double x, double T, double r, double b, double v);
    static double GVegaLeverage(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GRho(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GRhoFO(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GPhi(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GCarry(string CallPutFlag, double S, double x, double T, double r, double b, double v);
    static double GBlackScholesVariance(string CallPutFlag, double S, double x, double T, double r, double b, double v);

    static double GBlackScholesNGreeks(string OutPutFlag, string CallPutFlag, double S, double x, double T, double r, double b, double v, double dS);
    static double CGBlackScholes(string OutPutFlag, string CallPutFlag, double S, double x,
            double T, double r, double b, double v, double delta, double InTheMoneyProb, double ThetaDays);
    static double EGBlackScholes(string OutPutFlag, string CallPutFlag, double S, double x,
            double T, double r, double b, double v, double delta, double InTheMoneyProb, double ThetaDays);

    static double GBlackScholesVarianceNGreeks(string OutPutFlag, string CallPutFlag, double S, double x, double T, double r, double b, double v, double dS);

    //implied volatility for european options
    static double GBlackScholesImpVolBisection(string CallPutFlag, double S,
            double x,double T,double r,double b,double cm);
    static double GImpliedVolatilityNR(string CallPutFlag, double S, double x,
            double T, double r, double b, double cm, double epsilon);


    //perpetual options
    static double PerpetualOption(string CallPutFlag, double S, double X, double r, double b, double v);
    static double EPerpetualOption(string OutPutFlag, string CallPutFlag, double S, double X,
            double r, double b, double v, double dS);

    //American options
    static double Kc(double X, double T, double r, double b, double v);
    static double Kp(double X, double T, double r, double b, double v);
    static double phi(double S, double T, double gamma, double h, double i,
                  double r, double b, double v);
    static double phi2(double S, double T2, double gamma, double h, double i,
                           double r, double b, double v);
    static double ksi(double S, double T2, double gamma, double h, double I2, double I1, double t1, double r, double b, double v);

    static double BSAmericanCallApprox2002(double S, double X, double T, double r, double b, double v);
    static double BSAmericanApprox2002(string CallPutFlag, double S, double X, double T, double r, double b, double v);
    static double EBSAmericanApprox2002(string OutPutFlag, string CallPutFlag, double S, double X, double T,
            double r, double b, double v, double dS);

    static double BSAmericanCallApprox(double S, double X, double T, double r, double b, double v);
    static double BSAmericanApprox(string CallPutFlag, double S, double X, double T, double r, double b, double v);
    static double EBSAmericanApprox(string OutPutFlag, string CallPutFlag, double S, double X, double T,
            double r, double b, double v, double dS);
    

    static double BAWAmericanCallApprox(double S, double X, double T, double r, double b, double v);
    static double BAWAmericanPutApprox(double S, double X, double T, double r, double b, double v);
    static double BAWAmericanApprox(string CallPutFlag, double S, double X, double T, double r, double b, double v);
    static double EBAWAmericanApprox(string OutPutFlag, string CallPutFlag, double S, double X, double T,
            double r, double b, double v, double dS);

    //implied volatility for american options
    static double BAWAmericanImpVolBisection(string CallPutFlag, double S, double x, double T, double r, double b, double cm);
    static double BSAmerican2002ImpVolBisection(string CallPutFlag, double S, double x, double T, double r, double b, double cm);
    
    




    

private:

    static double Min(double x, double y)
    {
        return (x<y) ? x:y;
    }
    static double Max(double x, double y)
    {
        return (x>y) ? x : y;
    }

    static double Factorial(double n)
    {
	if(n<=0)return 1.0;
	double res=1.0;
	for (double i = 2.0; i < (n + 1); i++)
	{
		     res *= i;
	}
	return res;
    }

    static double Combination(double n, double r)
    {
            double nfloor = floor(n);
            double rfloor = floor(r);

            if ((n < 1) || (r < 0) || (r > n) || (r != rfloor) || (n != nfloor))
            {
                return 0.0;
            }
            return Factorial(n)/(Factorial(r)*Factorial(n-r));
    }

    static double ArcSin(double x)
    {
        return asin(x);
    }

    static double Sign(double x)
    {
        return (x<0.0) ? -1.0 : 1.0;
    }







};


#endif	/* OPTIONUTIL_H */

